#include "Uart.h"
#include <stdarg.h>
#include <stdio.h>
#include <string.h>

#define DataSize 256

uint8_t Serial_RxFlag = 0;              //串口接收标志位
uint8_t Serial_RxPacket[DataSize];         //缓存数据包
volatile int data = 0;



void Uart_K210_Init(void)
{
    NVIC_ClearPendingIRQ(UART_1_INST_INT_IRQN); // 清除中断标志位 防止系统启动后立即误进入 ISR；
    NVIC_EnableIRQ(UART_1_INST_INT_IRQN);       // 使能串口中断
}

void UART_1_INST_IRQHandler(void)
{
    // static uint8_t RxState = 0;		//定义表示当前状态机状态的静态变量 静态变量，只初始化一次 
	// static uint8_t pRxPacket = 0;	//定义表示当前接收数据位置的静态变量
    uint8_t RxData;
    switch ( DL_UART_getPendingInterrupt(UART_1_INST) )
    {
        case DL_UART_IIDX_RX: // 接收中断
            DL_UART_clearInterruptStatus(UART_1_INST,DL_UART_INTERRUPT_RX);
            RxData = DL_UART_Main_receiveData(UART_1_INST); // 接收数据
            Uart_Send_Char(RxData);
            // if(pRxPacket == DataSize - 1){ RxState = 0; 
            // Uart_Send_String("Overflu!\r\n");} //防止数据溢出
            // switch(RxState)
            // {
            //     case 0: 
            //             if (RxData == '@' && Serial_RxFlag == 0)		//如果数据确实是包头，并且上一个数据包已处理完毕
            //             {
            //                 memset(Serial_RxPacket, 0, DataSize);  // 清空数组，将所有元素设置为 0
            //                 RxState = 1;			//置下一个状态
            //                 pRxPacket = 0;			//数据包的位置归零
            //             }
            //         break;
            //     case 1:
            //             if ( RxData == '#' ){ RxState = 2;	}   //如果接收到了包尾置下一个状态
            //             else{                                   //接收到了正常的数据
            //                 Serial_RxPacket[pRxPacket] = RxData;		//将数据存入数据包数组的指定位置
            //                 pRxPacket ++;			//数据包的位置自增
            //             }
            //         break;
            //     case 2:
            //             RxState = 0;	
            //             Serial_RxPacket[pRxPacket] = '\0';	//将收到的字符数据包添加一个字符串结束标志
            //             Serial_RxFlag = 1;		//接收数据包标志位置1，成功接收一个数据包
            //         break;
            //     default:
            //         break;
            // }
            
        break;
        
    default: // 其他的串口中断
        break;
    }
}


void Uart_Init(void)
{
    NVIC_ClearPendingIRQ(UART_0_INST_INT_IRQN); // 清除中断标志位 防止系统启动后立即误进入 ISR；
    NVIC_EnableIRQ(UART_0_INST_INT_IRQN);       // 使能串口中断
}


void UART_0_INST_IRQHandler(void)
{
    static uint8_t RxState = 0;		//定义表示当前状态机状态的静态变量 静态变量，只初始化一次 
	static uint8_t pRxPacket = 0;	//定义表示当前接收数据位置的静态变量
    uint8_t RxData;
    switch ( DL_UART_getPendingInterrupt(UART_0_INST) )
    {

        case DL_UART_IIDX_RX: // 接收中断
            DL_UART_clearInterruptStatus(UART_0_INST,DL_UART_INTERRUPT_RX);
            RxData = DL_UART_Main_receiveData(UART_0_INST); // 接收数据
            if(pRxPacket == DataSize - 1){ RxState = 0; 

            Uart_Send_String("Overflu!\r\n");} //防止数据溢出
            
            switch(RxState)
            {
                case 0: 
                        if (RxData == '@' && Serial_RxFlag == 0)		//如果数据确实是包头，并且上一个数据包已处理完毕
                        {
                            memset(Serial_RxPacket, 0, DataSize);  // 清空数组，将所有元素设置为 0
                            RxState = 1;			//置下一个状态
                            pRxPacket = 0;			//数据包的位置归零
                        }
                    break;
                case 1:
                        if ( RxData == '#' ){ RxState = 2;	}   //如果接收到了包尾置下一个状态
                        else{                                   //接收到了正常的数据
                            Serial_RxPacket[pRxPacket] = RxData;		//将数据存入数据包数组的指定位置
                            pRxPacket ++;			//数据包的位置自增
                        }
                    break;
                case 2:
                        RxState = 0;	
                        Serial_RxPacket[pRxPacket] = '\0';	//将收到的字符数据包添加一个字符串结束标志
                        Serial_RxFlag = 1;		//接收数据包标志位置1，成功接收一个数据包
                        DL_GPIO_togglePins(LED_PORT, LED_D2_PIN);
                    break;
                default:
                    break;
            }
            
        break;
        
    default: // 其他的串口中断
        break;
    }
}

static uint8_t Data_CMD(char * CMD)
{
    return strcmp((char*)Serial_RxPacket, (char*)CMD) == 0 ? 1 : 0;
}


// UART接收到指令后处理
void Uart_Rx_Process(void)
{
    static int Speed_Base = 700;

    if (Serial_RxFlag) // 检查是否接收到指令
    {
        if (Data_CMD("OW") == 1) // 示例指令比较
        {
                 Motor_Control(700, 700);
            Uart_Send_String("Forword\r\n"); // 发送成功消息
        }
        
        if (Data_CMD("OS") == 1)
        {
            Motor_Control(-Speed_Base, -Speed_Base); 
            Uart_Send_String("Back\r\n"); // 发送成功消息

        }

        if (Data_CMD("OA") == 1)
        {
            Motor_Control(-Speed_Base, Speed_Base);
            Uart_Send_String("Left\r\n"); // 发送成功消息
        }

        if (Data_CMD("OD") == 1)
        {
            Motor_Control(Speed_Base, -Speed_Base);
            Uart_Send_String("Right\r\n"); // 发送成功消息
        }
        
        if (Data_CMD("OQ") == 1)
        {
            
            Motor_Control(0, 0);
            Uart_Send_String("Stop\r\n"); // 发送成功消息
        }

        if (Data_CMD("OP") == 1)
        {
            Speed_Base += 10;
            if(Speed_Base > 180){
                Speed_Base = 180;
            }
            Motor_Control(Speed_Base, Speed_Base);
            Sprintf("Speed Set:%d\r\n",Speed_Base); // 发送成功消息
        }

        if (Data_CMD("OL") == 1)
        {
            Speed_Base -= 10;
            if(Speed_Base < 0){
                Speed_Base = 0;
            }
            Motor_Control(Speed_Base, Speed_Base);
            Sprintf("Speed Set:%d\r\n",Speed_Base); // 发送成功消息
        }

        if (Data_CMD("OE") == 1)
        {
            Uart_Send_String("State_Change\r\n"); // 发送成功消息
            Motor_Control(0, 0);
            Contrl_Flag ++;
            if(Contrl_Flag >= 3 ){
                Contrl_Flag = 0;
            }
            switch (Contrl_Flag) 
            {
                case UART_Contrl:Uart_Send_String("UART_State\r\n"); // 发送成功消息
                    break;
                case MPU_Contrl: Uart_Send_String("MPU_State\r\n"); // 发送成功消息
                    break;
                case Track_Contrl:Uart_Send_String("Track_State\r\n"); // 发送成功消息
                    break;
                default:Uart_Send_String("State Err\r\n"); // 发送成功消息
                    break;
            }
        }        

        Serial_RxFlag = 0; // 重置标志，以便下一次接收指令
    }
}


void Uart_Send_Char(char ch)
{
    while (DL_UART_isBusy(UART_0_INST) == true){}; // 当串口0忙的时候等待，不忙的时候再发送传进来的字符
    DL_UART_Main_transmitData(UART_0_INST, ch); // 发送单个字符
}

void Uart_Send_String(char *string)
{
    if (string == NULL)
        return; // 检查空指针

    uint8_t length = strlen(string); // 计算字符长度
    for (size_t i = 0; i < length; i++)
    {
        Uart_Send_Char(string[i]);
    }
    Uart_Send_Char('\n'); // 可选：发送换行符或结束符
}

void Sprintf(char *format, ...) // 使用printf的方式发送字符
{
    char String[100];              // 定义字符数组
    va_list arg;                   // 定义可变参数列表数据类型的变量arg
    va_start(arg, format);         // 从format开始，接收参数列表到arg变量
    vsprintf(String, format, arg); // 使用vsprintf打印格式化字符串和参数列表到字符数组中
    va_end(arg);                   // 结束变量arg
    Uart_Send_String(String);      // 串口发送字符数组（字符串）
}